<?php

namespace app\controller;

use app\BaseController;
use DateTime;
use DateTimeZone;
use Lcobucci\JWT\Signer\Ecdsa\Sha256;
use think\facade\Db;
use think\facade\Request;
use WeChatPay\Builder;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Formatter;
use WeChatPay\Util\PemUtil;
class Order extends BaseController
{

    public function index() {
        $token = Request::header('Authorization');
    if (empty($token) || !preg_match('/^Bearer\s+(.+)$/i', $token, $matches)) {
        return json(['code' => 401, 'msg' => '未授权访问']);
    }
    $token = $matches[1];
    $user = Db::name('think_user')->where('token', $token)->find();
    if (!$user) {
        return json(['code' => 401, 'msg' => '无效token']);
    }
    $userId = $user['id'];

    $type = $this->request->post('type', 0);

    $query = Db::name('think_order')->where('user_id', $userId);

    switch (intval($type)) {
        case 1: // 待付款
            $query->whereIn('status', [0, 1]);
            break;
        case 2: // 待收货
            $query->where('status', 2);
            break;
        case 3: // 已完成/已退款
            $query->whereIn('status', [4, 5]);
            break;
        case 4: // 已取消
            $query->where('status', 6);
            break;
        case 0:
        default: // 全部
            // 不加额外条件
            break;
    }

    $orders = $query->order('created_at', 'desc')->select()->toArray();

    $result = [];
    foreach ($orders as $order) {
        $result[] = [
            'id'         => $order['id'],
            'orderNo'    => $order['order_number'],
            'create_date'=> $order['created_at'],
            'goods'      => json_decode($order['goods_json'], true),
            'status'     => $order['status'],
            'amount'     => $order['amount'],
            'payAmount'  => $order['pay_amount']
        ];
    }

    return json([
        'code' => 200,
        'msg'  => '获取成功',
        'data' => $result
    ]);
    }

    public function create()
{
    $token = Request::header('Authorization');
    if (empty($token) || !preg_match('/^Bearer\s+(.+)$/i', $token, $matches)) {
        return json(['code' => 401, 'msg' => '未授权访问']);
    }
    $token = $matches[1];
    $user = Db::name('think_user')->where('token', $token)->find();
    if (!$user) {
        return json(['code' => 401, 'msg' => '无效token']);
    }
    $userId = $user['id'];
    $data = $this->request->post('data');
    $amount = 0;

    // 解析商品数组
    if (is_string($data)) {
        $goods = json_decode($data, true);
    } else {
        $goods = $data;
    }
    if (!is_array($goods) || empty($goods)) {
        return json(['code' => 400, 'msg' => '商品信息有误', "data"=>$data]);
    }

    $goodsDetail = [];
    foreach ($goods as $item) {
        $product = Db::name('think_goods')->where('id', $item['id'])->find();
        if (!$product) {
            return json(['code' => 400, 'msg' => '商品不存在: id=' . $item['id']]);
        }
        $buyCount = intval($item['count']);
        $price = intval($product['price']);
        $amount += $price * $buyCount;
        
        $goodsDetail[] = [
            'id'        => $product['id'],
            'name'      => $product['name'],
            'image'     => $product['image'],
            'desc'      => $product['desc'],
            'price'     => $price,
            'linedPrice'=> isset($product['linedPrice']) ? intval($product['linedPrice']) : 0,
            'buyCount'  => $buyCount
        ];
    }
    // 生成唯一订单号
    $orderNumber = 'EC' . $userId . date('YmdHis') . mt_rand(1000, 9999);
    // 保存订单
    $orderData = [
        'order_number' => $orderNumber,
        'user_id'      => $userId,
        'goods_json'   => json_encode($goodsDetail, JSON_UNESCAPED_UNICODE),
        'amount'       => $amount,
        'status'       => 0, // 预订单
        'created_at'   => date('Y-m-d H:i:s'),
        'updated_at'   => date('Y-m-d H:i:s'),
    ];
    $res = Db::name('think_order')->insert($orderData);

    if ($res) {
        return json([
            "code" => 200,
            "msg"  => "创建成功",
            "data" => [
                "order_number" => $orderNumber
            ]
        ]);
    } else {
        return json([
            "code" => 500,
            "msg"  => "创建失败"
        ]);
    }
}

    public function detail() {
        $token = Request::header('Authorization');
    if (empty($token) || !preg_match('/^Bearer\s+(.+)$/i', $token, $matches)) {
        return json(['code' => 401, 'msg' => '未授权访问']);
    }
    $token = $matches[1];
    $user = Db::name('think_user')->where('token', $token)->find();
    if (!$user) {
        return json(['code' => 401, 'msg' => '无效token']);
    }
    $userId = $user['id'];
    $orderNumber = $this->request->post('order_number');
    if (empty($orderNumber)) {
        return json([
            "code" => 400,
            "msg"  => "缺少订单号"
        ]);
    }
    $order = Db::name('think_order')->where('order_number', $orderNumber)->find();
    if (!$order) {
        return json([
            "code" => 404,
            "msg"  => "订单不存在"
        ]);
    }
    // 解析商品信息
    $goods = json_decode($order['goods_json'], true);
    // 查询收货地址信息
    $addressInfo = null;
    if (!empty($order['address_id'])) {
        $address = Db::name('think_address')->where('id', $order['address_id'])->find();
        if ($address) {
            $addressInfo = [
                'name'    => $address['name'],
                'phone'   => $address['phone'],
                'address' => $address['province'] . $address['city'] . $address['district'] . $address['address']
            ];
        }
    }
    return json([
        "code" => 200,
        "msg"  => "获取成功",
        "data" => [
            "order_number" => $order['order_number'],
            "status"       => $order['status'],
            "data"         => $goods,
            "amount"=>$order["amount"],
            "pay_amount"=>$order["pay_amount"],
            "address"=>$addressInfo,
            "deliver_type"=>$order["deliver_type"],
            "remarks"=>$order["remarks"],
            "receive_time"=>$order["receive_time"],
            "created_at"=>$order["created_at"],
            "pay_time"=>$order["pay_time"],
            "update_time"=>  $order["updated_at"],
            "prepay_id_time"=>  $order["prepay_id_time"],
        ]
    ]);
    }

    public function pay() {
        try {
    $token = Request::header('Authorization');
    if (empty($token) || !preg_match('/^Bearer\s+(.+)$/i', $token, $matches)) {
        return json(['code' => 401, 'msg' => '未授权访问']);
    }
    $token = $matches[1];
    $user = Db::name('think_user')->where('token', $token)->find();
    if (!$user) {
        return json(['code' => 401, 'msg' => '无效token']);
    }
    $userId = $user['id'];
        $orderNumber = $this->request->post('order_number');
        $deliver_type = $this->request->post('deliver_type');
        $address_id = $this->request->post('address_id');
        $receive_time = $this->request->post('receive_time');
        $remarks = $this->request->post('remarks');
        $openId = $user['openid'];
        $order = Db::name('think_order')->where('user_id', $userId)->where('order_number', $orderNumber)->find();
        if (!$order) {
            return json(['code' => 404, 'msg' => '订单不存在']);
        }
        $amount = intval($order['amount']);
        $status = $order['status'];
        $mchid = '1551022781';
        $appid = 'wxd3adf3a5dfa16747';
        $prepay_id = '';
        $timestamp = (string)Formatter::timestamp();
        $merchantPrivateKeyFilePath = 'file://' . root_path() . 'cert/1551022781_20250625_cert/apiclient_key.pem';
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        if ($status == 0) {
            # code...
            // 更新订单信息
            $goodsArr = json_decode($order['goods_json'], true);
            $descArr = [];
            foreach ($goodsArr as $g) {
                $descArr[] = $g['name'] . 'x' . $g['buyCount'];
            }
            $description = implode('，', $descArr);
            // 微信支付参数
            $notifyUrl = 'https://www.pfjsg.cn/index.php/Order/confirm'; // 支付回调地址
            $merchantCertificateSerial = "350D3755110C716B9DD29F775782D2B7D9D7D285";
            $platformPublicKeyFilePath = 'file://' . root_path() . 'cert/1551022781_20250625_cert/pub_key.pem';
            $twoPlatformPublicKeyInstance = Rsa::from($platformPublicKeyFilePath, Rsa::KEY_TYPE_PUBLIC);
            $platformPublicKeyId = 'PUB_KEY_ID_0115510227812025062500381569001202';
            $instance = Builder::factory([
                'mchid'      => $mchid,
                'serial'     => $merchantCertificateSerial,
                'privateKey' => $merchantPrivateKeyInstance,
                'certs'      => [
                    $platformPublicKeyId => $twoPlatformPublicKeyInstance,
                ],
            ]);
            $date = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
            $date->modify('+15 minutes');
            $time_expire = $date->format('Y-m-d\TH:i:sP');
            $response = $instance->chain('/v3/pay/transactions/jsapi')->post([
                'json' => [
                    "appid"=> $appid,
                    "mchid"=>$mchid,
                    "description"=> $description,
                    "out_trade_no"=>$orderNumber,
                    "time_expire"=> $time_expire,
                    "notify_url"=>$notifyUrl,
                    "amount"=>[
                        "total"=>$amount,
                        "currency"=>"CNY"
                    ],
                "payer"=>[
                    "openid"=>$openId
                ]
            ],
            'headers' => [
            'Authorization' => 'Authorization',
            'Accept'=>'application/json',
            'Content-Type'=>'application/json'
        ],
        ]);
        $body = (string)$response->getBody();
        $data = json_decode($body, true);
        $prepay_id = $data["prepay_id"];
            Db::name('think_order')->where('user_id', $userId)->where('order_number', $orderNumber)->update([
                'deliver_type' => $deliver_type,
                'address_id'   => $address_id,
                'receive_time' => $receive_time,
                'remarks'      => $remarks,
                'updated_at'   => date('Y-m-d H:i:s'),
                "status"=>1,
                "prepay_id"=> $prepay_id,
                "prepay_id_time"=> date('Y-m-d H:i:s'),
            ]);
        } else if ($status == 1) {
            //支付过一次了还没支付成功
            $prepay_id = $order['prepay_id'];
        } else {
            //不能够再支付
            return json([
                'code' => 400,
                'msg'  => '支付失败'
            ]);
        }
        $nonceStr = (string)Formatter::nonce();
        $params = [
            'appId'     => $appid,
            'timeStamp' => $timestamp,
            'nonceStr'  => $nonceStr,
            'package'   => 'prepay_id=' . $prepay_id
        ];
        $params += ['paySign' => Rsa::sign(
    Formatter::joinedByLineFeed(...array_values($params)),
    $merchantPrivateKeyInstance
), 'signType' => 'RSA'];
        return json([
            'code' => 200,
            'msg'  => '获取支付参数成功',
            'data' => $params
        ]);
    } catch (\Throwable $e) {
        return json([
            'code' => 500,
            'msg'  => '支付下单失败: ' . $e->getMessage()
        ]);
    }
    }

    public function confirm() {
    $content = file_get_contents('php://input');
    file_put_contents(root_path() . 'runtime/request_params.log', date('Y-m-d H:i:s') . ' ' . $content . PHP_EOL, FILE_APPEND);
    $data = json_decode($content, true);
    if (!isset($data['resource'])) {
        return json(['code' => 400, 'msg' => '无效回调数据']);
    }
    $resource = $data['resource'];
    $apiV3Key = '09876543211234567890098765432112'; // 请替换为你的APIv3密钥
    $ciphertext = $resource['ciphertext'];
    $nonce = $resource['nonce'];
    $associated_data = $resource['associated_data'];
    $json = AesGcm::decrypt($ciphertext, $apiV3Key, $nonce, $associated_data);
    $trade = json_decode($json,true);
    $appid = $trade["appid"];
    $mchid = $trade["mchid"];
    $out_order_no = $trade["out_trade_no"];
    // $transaction_id = $trade["transaction_id"];
    // $openid = $trade["payer"][0]["openid"];
    $total_amount = $trade["amount"]["total"];
    Db::name('think_order')->where('order_number', $out_order_no)->update([
        'status'    => 2,
        'pay_time'  => date('Y-m-d H:i:s'),
        'updated_at'=> date('Y-m-d H:i:s'),
        'pay_amount'=>$total_amount
    ]);
    }

    public function cancel() {
        $token = Request::header('Authorization');
    if (empty($token) || !preg_match('/^Bearer\s+(.+)$/i', $token, $matches)) {
        return json(['code' => 401, 'msg' => '未授权访问']);
    }
    $token = $matches[1];
    $user = Db::name('think_user')->where('token', $token)->find();
    if (!$user) {
        return json(['code' => 401, 'msg' => '无效token']);
    }
    $userId = $user['id'];
    $orderNumber = $this->request->post('order_number');
    if (empty($orderNumber)) {
        return json(['code' => 400, 'msg' => '缺少订单号']);
    }
    $order = Db::name('think_order')->where('order_number', $orderNumber)->find();
    if (!$order) {
        return json(['code' => 404, 'msg' => '订单不存在']);
    }
    if ($order['user_id'] != $userId) {
        return json(['code' => 403, 'msg' => '无权操作该订单']);
    }
    // 只有未支付和待支付状态允许取消
    if (!in_array($order['status'], [0, 1])) {
        return json(['code' => 400, 'msg' => '当前订单状态不可取消']);
    }
    Db::name('think_order')->where('order_number', $orderNumber)->update([
        'status' => 6,
        'updated_at' => date('Y-m-d H:i:s')
    ]);
    return json(['code' => 200, 'msg' => '订单已取消']);
    }

    public function sendway() {
        return json(['code' => 200, 'msg' => 'success', 'data'=>[
            ['id'=>0,
            'name'=>'到店自提'],
            ['id'=>1,
            'name'=>'外卖配送'],
        ]]);
    }
}